#include "rknn_Detector.hpp"  

// 构造函数的实现
RKNNDetector::RKNNDetector(const std::string& model_path, int input_width, int input_height, float conf_thresh, float nms_thresh, int nc)
: model_path_(model_path), INPUT_WIDTH_(input_width), INPUT_HEIGHT_(input_height), CONF_THRESH_(conf_thresh), NMS_THRESH_(nms_thresh),
nc_(nc), ctx_(0), n_input_(0), n_output_(0), is_inited_(false) 
{
    // CLASSES_ = {"enemy"};  // 初始化类别名称
    // CLASSES_ = {"cilcle", "cross"};  // 初始化类别名称
    // CLASSES_ = {"Green_pillar", "Red_pillar", "Blue_pillar", "White_pillar", "Black_pillar"};  
    CLASSES_ = {"nothing", "Green_pillar", "Red_pillar", "Blue_pillar", "White_pillar", "Black_pillar", "Bull_circle", "Filed_circle"};  
    // CLASSES_ = {"nothing", "Black_pillar", "White_pillar", "Red_pillar", "Green_pillar", "Blue_pillar", "Bull_circle", "Filed_circle"};  
}

// 析构函数实现
RKNNDetector::~RKNNDetector() 
{
    release();
}

// 初始化函数
bool RKNNDetector::init()
{
    // 读取模型文件
    std::ifstream model_file(model_path_, std::ios::binary | std::ios::ate);
    if(!model_file.is_open())
    {
        std::cerr << "Failed to open model file: " << model_path_ << std::endl;
        return false;
    }
    std::streamsize model_size = model_file.tellg();
    model_file.seekg(0, std::ios::beg);
    std::vector<char> model_buffer(model_size);
    if(!model_file.read(model_buffer.data(), model_size))
    {
        std::cerr << "Failed to read model file" << std::endl;
        return false;
    }

    // 初始化RKNN上下文
    int ret = rknn_init(&ctx_, model_buffer.data(), model_size, 0, NULL);
    if(ret < 0)
    {
        std::cerr << "RKNN init failed, error code: " << ret << std::endl;
        return false;
    }

    // 设置NPU核心
    ret = rknn_set_core_mask(ctx_, RKNN_NPU_CORE_AUTO);
    if(ret < 0)
    {
        std::cerr << "Set NPU core mask failed, error code: " << ret << std::endl;
        rknn_destroy(ctx_);
        return false;
    }

    // 获取输入输出数据
    rknn_input_output_num io_num;
    ret = rknn_query(ctx_, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
    if(ret < 0)
    {
        std::cerr << "Query input/output num failed" << std::endl;
        rknn_destroy(ctx_);
        return false;
    }
    n_input_ = io_num.n_input;
    n_output_ = io_num.n_output;

    // 预计算输出尺寸
    output_attrs_.resize(n_output_);
    output_sizes_precomputed_.resize(n_output_);
    for(uint32_t i = 0; i < n_output_; ++i)
    {
        output_attrs_[i].index = i;
        ret = rknn_query(ctx_, RKNN_QUERY_OUTPUT_ATTR, &output_attrs_[i], sizeof(rknn_tensor_attr));
        if(ret < 0)
        {
            std::cerr << "Query output " << i << " attribute failed" << std::endl;
            rknn_destroy(ctx_);
            return false;
        }
        int elem_cout = 1;
        for(uint32_t j = 0; j < output_attrs_[i].n_dims; ++j)
        {
            elem_cout *= output_attrs_[i].dims[j];
        }
        output_sizes_precomputed_[i] = elem_cout;
    }

    // // 在 init() 中添加，打印输出维度
    // for (auto& attr : output_attrs_) 
    // {
    //     std::cout << "\n===== 输出 " << attr.index << " =====" << std::endl;
    //     std::cout << "量化参数: scale=" << attr.scale << " zp=" << attr.zp << std::endl;
    //     std::cout << "维度: [";
    //     for (uint32_t j = 0; j < attr.n_dims; ++j) 
    //     {
    //         std::cout << attr.dims[j] << (j < attr.n_dims - 1 ? ", " : "");
    //     }
    //     std::cout << "]" << std::endl;
    //     std::cout << "格式: " << (attr.fmt == RKNN_TENSOR_NHWC ? "NHWC" : 
    //                              (attr.fmt == RKNN_TENSOR_NCHW ? "NCHW" : "其他")) << std::endl;
    // }

    // 查询输入张量信息
    rknn_tensor_attr input_attr;
    memset(&input_attr, 0, sizeof(input_attr));  // 清空结构体
    input_attr.index = 0;
    ret = rknn_query(ctx_, RKNN_QUERY_INPUT_ATTR, &input_attr, sizeof(input_attr));
    if (ret != RKNN_SUCC) 
    {
        std::cerr << "查询输入属性失败，错误代码: " << ret << std::endl;
        rknn_destroy(ctx_);
        return false;
    }

    // 正确打印输入属性
    // std::cout << "===== 输入属性 =====" << std::endl;
    // std::cout << "名称: " << input_attr.name << std::endl;
    // std::cout << "维度: [";
    // for (uint32_t j = 0; j < input_attr.n_dims; ++j) {
    //     std::cout << input_attr.dims[j] << (j < input_attr.n_dims - 1 ? ", " : "");
    // }
    // std::cout << "]" << std::endl;
    // std::cout << "格式: " << (input_attr.fmt == RKNN_TENSOR_NHWC ? "NHWC" : 
    //                         (input_attr.fmt == RKNN_TENSOR_NCHW ? "NCHW" : "其他")) << std::endl;
    // std::cout << "类型: " << (input_attr.type == RKNN_TENSOR_FLOAT32 ? "FLOAT32" :
    //                         (input_attr.type == RKNN_TENSOR_INT8 ? "INT8" : "其他")) << std::endl;
    // std::cout << "量化参数: scale=" << input_attr.scale << " zp=" << input_attr.zp << std::endl;

    // 在查询输入属性后添加
    input_scale_ = input_attr.scale;
    input_zero_point_ = input_attr.zp;

    // 初始化输入输出结构体
    inputs_.resize(n_input_);
    memset(inputs_.data(), 0, sizeof(rknn_input)*n_input_);
    inputs_[0].index = 0;
    inputs_[0].type = RKNN_TENSOR_INT8;
    inputs_[0].fmt = RKNN_TENSOR_NHWC;
    inputs_[0].pass_through = 0;

    outputs_.resize(n_output_);
    for(size_t i = 0; i < n_output_; ++i)
    {
        outputs_[i].want_float = 1; 
    }

    is_inited_ = true;
    std::cout << "Model initialized successfully" << std::endl;
    return true;
}

// 处理单帧图像
std::vector<Bbox> RKNNDetector::process(cv::Mat& frame)
{
    if(!is_inited_)
    {
        std::cerr << "Model not initialized, call init() first" << std::endl;
        return {};
    }
    if(frame.empty())
    {
        std::cerr << "Input frame is empty" << std::endl;
        return {};
    }

    // 图像预处理
    float scale, pad_w, pad_h;
    cv::Mat input_img = preprocess(frame, scale, pad_w, pad_h);

    // 设置输入
    inputs_[0].buf = input_img.data;
    inputs_[0].size = INPUT_WIDTH_ * INPUT_HEIGHT_ * 3;
    int ret = rknn_inputs_set(ctx_, n_input_, inputs_.data());
    if(ret < 0)
    {
        std::cerr << "Set inputs failed, error code: " << ret << std::endl;
        return {};
    }

    // 模型推理
    ret = rknn_run(ctx_, NULL);
    if(ret < 0)
    {
        std::cerr << "Inference failed, error code: " << ret << std::endl;
        return {};
    }

    // 获取输出
    ret = rknn_outputs_get(ctx_, n_output_, outputs_.data(), NULL);
    if(ret < 0)
    {
        std::cerr << "Get outputs failed, error code: " << ret << std::endl;
        return {};
    }

    // 解析输出后处理
    std::vector<float*> output_ptrs;
    std::vector<int> output_sizes;
    for(uint32_t i = 0; i < n_output_; ++i)
    {
        output_ptrs.push_back((float*)outputs_[i].buf);
        output_sizes.push_back(output_sizes_precomputed_[i]);
    }
    std::vector<Bbox> boxes = postprocess(output_ptrs, output_sizes, scale, pad_w, pad_h, frame);

    // 释放输出缓冲区
    rknn_outputs_release(ctx_, n_output_, outputs_.data());

    return boxes;
}

// 定义sigmoid函数（将logits转换为0~1的概率）
float sigmoid(float x) 
{
    // return 1.0f / (1.0f + expf(-x)); // 核心：将任意值映射到0~1
    return x;
}

// 绘制检测结果
void RKNNDetector::draw(cv::Mat& frame, const std::vector<Bbox>& boxes)
{
    for(const auto& box : boxes)
    {
        // 绘制边界框
        cv::rectangle(frame, cv::Point((int)box.x1, (int)box.y1), 
                             cv::Point((int)box.x2, (int)box.y2),
                             cv::Scalar(0, 0, 255), 3);
        // 绘制标签
        std::string label = CLASSES_[box.cls] + " " + std::to_string(box.conf).substr(0, 4);
        cv::putText(frame, label, cv::Point((int)box.x1, (int)box.y1 - 10), 
                                  cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 0, 255), 2);
    }
}

// 释放资源
void RKNNDetector::release()
{
    if(ctx_ != 0)
    {
        rknn_destroy(ctx_);
        ctx_ = 0;
    }
    is_inited_ = false;
}

// 判断初始化状态
bool RKNNDetector::isInited() const 
{
    return is_inited_;
}

// 预处理
cv::Mat RKNNDetector::preprocess(cv::Mat& frame, float& scale, float& pad_w, float& pad_h)
{
    cv::Mat img = frame.clone();    // 避免修改原图像
    float h = img.rows;
    float w = img.cols;

    // 计算缩放比例
    scale = std::min((float)INPUT_WIDTH_ / w, (float)INPUT_HEIGHT_ / h);
    int new_w = (int)std::round(w * scale);
    int new_h = (int)std::round(h * scale);

    // 缩放图像
    cv::resize(img, img, cv::Size(new_w, new_h), 0, 0, cv::INTER_LINEAR);

    // 计算填充量
    pad_w = (INPUT_WIDTH_ - new_w) / 2.0f;
    pad_h = (INPUT_HEIGHT_ - new_h) / 2.0f;

    // 填充边界
    cv::copyMakeBorder(img, img, (int)std::round(pad_h), (int)std::round(pad_h), (int)std::round(pad_w), (int)std::round(pad_w), 
        cv::BORDER_CONSTANT, cv::Scalar(114, 114, 114));

    // BGR转化RGB
    cv::cvtColor(img, img, cv::COLOR_BGR2RGB);

    // cv::transpose(img, img);  // HWC → CHW（维度变为 [3, 640, 640]）
    // cv::flip(img, img, 0);  // 垂直翻转通道（适配 NCHW 要求）

    // // 量化转换（保持原逻辑）
    // if(input_scale_ != 0) 
    // {
    //     img.convertTo(img, CV_8S, 1.0/input_scale_, input_zero_point_);
    // } 
    // else 
    // {
    //     img.convertTo(img, CV_8S);
    // }

    if(input_scale_ != 0)
    {
        img.convertTo(img, CV_8S, 1.0/(255 * input_scale_), input_zero_point_);
    }

    return img;
}

// 解码单个锚框
void RKNNDetector::decode_box(float* feat_ptr, const std::pair<float, float>& anchor, float scale, float pad_w, float pad_h,
    int grid_w, int grid_h, int stride, std::vector<Bbox>& boxes) 
{
    // 安全校验
    if (std::isnan(feat_ptr[0])) 
    {
        std::cerr << "无效的特征值: NaN" << std::endl;
        return;
    }
    // 修正公式（YOLOv5官方公式）：
    float cx = (sigmoid(feat_ptr[0]) + grid_w) * stride;
    float cy = (sigmoid(feat_ptr[1]) + grid_h) * stride;

    // 坐标有效性检查
    if (cx < -1000 || cx > 10000 || cy < -1000 || cy > 10000) 
    {
        std::cerr << "无效坐标: cx=" << cx << " cy=" << cy 
                  << " grid_w=" << grid_w << " grid_h=" << grid_h
                  << " stride=" << stride << std::endl;
        return;
    }

    // 修正公式：
    float w = expf(feat_ptr[2]) * anchor.first;
    float h = expf(feat_ptr[3]) * anchor.second;

    // 转换为左上角/右下角坐标（映射到原图）
    float x1 = (cx - w / 2 - pad_w) / scale;
    float y1 = (cy - h / 2 - pad_h) / scale;
    float x2 = (cx + w / 2 - pad_w) / scale;
    float y2 = (cy + h / 2 - pad_h) / scale;

        // 边界检查
    if (x1 > x2 || y1 > y2) 
    {
        std::cerr << "无效的边界框: x1=" << x1 << " y1=" << y1 
                  << " x2=" << x2 << " y2=" << y2 << std::endl;
        return;
    }

    // 置信度计算（目标置信度×类别置信度）
    float obj_conf = sigmoid(feat_ptr[4]); 
    float max_cls_conf = 0; 
    int cls_id = 0;

    // 查找最大类别置信度
    for(int c = 0; c < nc_; ++c)
    {
        float cls_conf = sigmoid(feat_ptr[5 + c]);
        if(cls_conf > max_cls_conf)
        {
            max_cls_conf = cls_conf;
            cls_id = c;
        }
    }
 
    float final_conf = obj_conf * max_cls_conf;

    if (final_conf > CONF_THRESH_) 
    {
                // 调试输出
        if (final_conf > 0.5) 
        {
            // std::cout << "检测到目标: cls=" << cls_id << " conf=" << final_conf
            //           << " 位置: (" << x1 << "," << y1 << ")-(" << x2 << "," << y2 << ")"
            //           << " 原始坐标: cx=" << cx << " cy=" << cy << " w=" << w << " h=" << h
            //           << std::endl;

            // std::cout << "Decoding box at grid(" << grid_w << "," << grid_h << ")"
            //       << " stride=" << stride
            //       << " anchor=(" << anchor.first << "," << anchor.second << ")\n"
            //       << "  Raw features: "
            //       << " cx=" << feat_ptr[0] << "->" << cx
            //       << " cy=" << feat_ptr[1] << "->" << cy
            //       << " w=" << feat_ptr[2] << "->" << w
            //       << " h=" << feat_ptr[3] << "->" << h
            //       << " conf=" << obj_conf << "*" << max_cls_conf << "=" << final_conf
            //       << std::endl;
        }
        boxes.push_back({x1, y1, x2, y2, final_conf, cls_id});  
    }

}

// 后处理
std::vector<Bbox> RKNNDetector::postprocess(std::vector<float*>& outputs, std::vector<int>& output_sizes,
    float scale, float pad_w, float pad_h, const cv::Mat& frame) 
{
    std::vector<Bbox> boxes;
    if (outputs.size() != 3) 
    {
        std::cerr << "Expected 3 outputs, got " << outputs.size() << std::endl;
        return boxes;
    }

    for (int i = 0; i < 3; ++i)  // 遍历3个输出层
    {  
        float* output_data = outputs[i];
        rknn_tensor_attr& attr = output_attrs_[i];
        
        // 从属性获取维度信息
        int channels = attr.dims[1];  // 30
        int height = attr.dims[2];    // 80/40/20
        int width = attr.dims[3];     // 80/40/20
        
        // 计算每个锚点的值数量 (5+5=10)
        int values_per_anchor = 5 + nc_;
        int num_anchors = 3;  // 每个输出层有3个锚点
        
        // 计算网格大小（特征图尺寸）
        int grid_size = height * width;
        
        // 按NCHW维度遍历：先通道、再高度、最后宽度
        for (int a = 0; a < num_anchors; ++a) 
        {
            // 当前锚点的起始通道索引
            int channel_start = a * values_per_anchor;
            
            for (int h = 0; h < height; ++h) 
            {
                for (int w = 0; w < width; ++w) 
                {
                    // 提取当前锚点的10个特征值
                    std::vector<float> feat(values_per_anchor);
                    
                    for (int c = 0; c < values_per_anchor; ++c) 
                    {
                        // 计算完整通道索引
                        int channel_idx = channel_start + c;
                        
                        // 计算内存位置索引：通道×网格大小 + 网格位置
                        int index = channel_idx * grid_size + (h * width + w);
                        
                        feat[c] = output_data[index];
                    }
                    
                    // 解码锚框
                    decode_box(feat.data(), ANCHORS_[i][a], 
                               scale, pad_w, pad_h, 
                               w, h, STRIDES_[i], boxes);
                }
            }
        }
    }

    // 应用NMS过滤重复框
    return apply_nms(boxes, NMS_THRESH_);
}

// IOU计算
float RKNNDetector::calculate_iou(const Bbox& box1, const Bbox& box2) 
{
    float inter_x1 = std::max(box1.x1, box2.x1);
    float inter_y1 = std::max(box1.y1, box2.y1);
    float inter_x2 = std::min(box1.x2, box2.x2);
    float inter_y2 = std::min(box1.y2, box2.y2);

    float inter_area = std::max(0.0f, inter_x2 - inter_x1) * std::max(0.0f, inter_y2 - inter_y1);
    float area1 = (box1.x2 - box1.x1) * (box1.y2 - box1.y1);
    float area2 = (box2.x2 - box2.x1) * (box2.y2 - box2.y1);

    return inter_area / (area1 + area2 - inter_area);
}

// NMS
// std::vector<Bbox> RKNNDetector::apply_nms(std::vector<Bbox>& boxes, float iou_threshold) 
// {
//     std::vector<Bbox> result;
//     std::vector<Bbox> filtered;  
//     std::vector<bool> suppressed(boxes.size(), false);

//     if (boxes.empty()) 
//         return result;

//     // 在过滤低置信度框时同时过滤超大框
//     float max_valid_area = 50000; // 假设目标最大面积不超过 100000 像素
//     for (auto& box : boxes) 
//     {
//         float area = (box.x2 - box.x1) * (box.y2 - box.y1);
//         if (box.conf > CONF_THRESH_ && area < max_valid_area) 
//         {
//             filtered.push_back(box);
//         }
//     }

//     // 按类别分组：cls_id -> 该类别所有框
//     std::unordered_map<int, std::vector<Bbox>> class_boxes;
//     for (auto& box : filtered) 
//     {
//         class_boxes[box.cls].push_back(box);
//     }

//     // 对每个类别单独处理
//     for (auto& [cls, group] : class_boxes) 
//     {
//         // 按置信度降序排序（仅对当前类别）
//         std::sort(group.begin(), group.end(), 
//             [](const Bbox& a, const Bbox& b) { 
//                 return a.conf > b.conf; 
//             });

//         // NMS 核心逻辑（仅处理当前类别）
//         std::vector<bool> suppressed(group.size(), false);
//         for (size_t i = 0; i < group.size(); ++i) 
//         {
//             if (suppressed[i]) 
//                 continue;
//             result.push_back(group[i]); // 保留高置信度框
//             // 抑制后续 IoU 过高的框
//             for (size_t j = i + 1; j < group.size(); ++j) 
//             {
//                 if (suppressed[j]) 
//                     continue;
//                 float iou = calculate_iou(group[i], group[j]);
//                 std::cout << "IOU between box " << i << " and " << j << ": " << iou 
//                         << " (threshold: " << NMS_THRESH_ << ")" << std::endl;
//                 if (iou > iou_threshold) 
//                 {
//                     suppressed[j] = true;
//                 }
//             }
//         }
//     }

//     return result;
// }

std::vector<Bbox> RKNNDetector::apply_nms(std::vector<Bbox>& boxes, float iou_threshold) 
{
    std::vector<Bbox> result;
    std::vector<Bbox> filtered;  

    if (boxes.empty()) 
        return result;

    // 1. 过滤低置信度框、超大框、超小框（先筛掉明显不合理的）
    float max_valid_area = 50000;   // 最大面积上限
    float min_valid_area = 1000;     // 最小面积下限（根据目标实际大小调整）
    for (auto& box : boxes) 
    {
        float area = (box.x2 - box.x1) * (box.y2 - box.y1);
        // 同时满足：置信度达标 + 面积在 [min, max] 范围内
        if (box.conf > CONF_THRESH_ && area < max_valid_area && area > min_valid_area) 
        {
            filtered.push_back(box);
        }
    }

    // 按类别分组
    std::unordered_map<int, std::vector<Bbox>> class_boxes;
    for (auto& box : filtered) 
    {
        class_boxes[box.cls].push_back(box);
    }

    // 每个类别中只保留面积最小的框
    for (auto& [cls, group] : class_boxes) 
    {
        if (group.empty()) 
            continue;

        // 按面积升序排序（最小的框排在最前）
        std::sort(group.begin(), group.end(), 
            [](const Bbox& a, const Bbox& b) { 
                float area_a = (a.x2 - a.x1) * (a.y2 - a.y1);
                float area_b = (b.x2 - b.x1) * (b.y2 - b.y1);
                return area_a < area_b;  // 面积小的在前
            });

        // 直接取面积最小的框（已通过面积下限过滤）
        result.push_back(group[0]);

        // 调试输出：打印选中的最小框信息
        float min_area = (group[0].x2 - group[0].x1) * (group[0].y2 - group[0].y1);
        std::cout << "类别: " << CLASSES_[cls] << " 选中最小框，面积: " << min_area 
                  << "，置信度: " << group[0].conf << std::endl;
    }

    return result;
}

// // NMS带包含关系检测
// std::vector<Bbox> RKNNDetector::apply_nms(std::vector<Bbox>& boxes, float iou_threshold) 
// {
//     std::vector<Bbox> result;
//     std::vector<Bbox> filtered;  

//     if (boxes.empty()) 
//         return result;

//     // 1. 过滤低置信度框和超大框
//     float max_valid_area = 50000; 
//     for (auto& box : boxes) 
//     {
//         float area = (box.x2 - box.x1) * (box.y2 - box.y1);
//         if (box.conf > CONF_THRESH_ && area < max_valid_area) 
//         {
//             filtered.push_back(box);
//         }
//     }

//     // 2. 按类别分组
//     std::unordered_map<int, std::vector<Bbox>> class_boxes;
//     for (auto& box : filtered) 
//     {
//         class_boxes[box.cls].push_back(box);
//     }

//     // 3. 对每个类别单独处理
//     for (auto& [cls, group] : class_boxes) 
//     {
//         // 3.1 按置信度降序排序
//         std::sort(group.begin(), group.end(), 
//             [](const Bbox& a, const Bbox& b) { 
//                 return a.conf > b.conf; 
//             });

//         // 3.2 执行NMS
//         std::vector<bool> suppressed(group.size(), false);
//         std::vector<Bbox> nms_result;
//         for (size_t i = 0; i < group.size(); ++i) 
//         {
//             if (suppressed[i]) 
//                 continue;
//             nms_result.push_back(group[i]);
//             for (size_t j = i + 1; j < group.size(); ++j) 
//             {
//                 if (suppressed[j]) 
//                     continue;
//                 float iou = calculate_iou(group[i], group[j]);
//                 if (iou > iou_threshold) 
//                 {
//                     suppressed[j] = true;
//                 }
//             }
//         }

//         // 3.3 检测包含关系，保留最小框
//         if (nms_result.size() >= 2)  // 当存在两个及以上框时检查
//         {
//             std::vector<Bbox> final_group;
//             std::vector<bool> is_contained(nms_result.size(), false);

//             // 计算每个框的面积
//             std::vector<float> areas;
//             for (auto& box : nms_result) 
//             {
//                 areas.push_back((box.x2 - box.x1) * (box.y2 - box.y1));
//             }

//             // 检查包含关系
//             for (size_t i = 0; i < nms_result.size(); ++i) 
//             {
//                 if (is_contained[i]) continue;
//                 for (size_t j = 0; j < nms_result.size(); ++j) 
//                 {
//                     if (i == j || is_contained[j]) continue;

//                     // 判断i是否包含j
//                     bool i_contains_j = (nms_result[i].x1 <= nms_result[j].x1 &&
//                                         nms_result[i].y1 <= nms_result[j].y1 &&
//                                         nms_result[i].x2 >= nms_result[j].x2 &&
//                                         nms_result[i].y2 >= nms_result[j].y2);

//                     // 被包含的框标记为待删除
//                     if (i_contains_j) 
//                     {
//                         is_contained[j] = true;  // j被包含，标记
//                     }
//                 }
//             }

//             // 收集未被包含的框
//             for (size_t i = 0; i < nms_result.size(); ++i) 
//             {
//                 if (!is_contained[i]) 
//                 {
//                     final_group.push_back(nms_result[i]);
//                 }
//             }

//             // 如果筛选后仍有多个框，取面积最小的（可选逻辑）
//             if (final_group.size() >= 2) 
//             {
//                 std::sort(final_group.begin(), final_group.end(),
//                     [](const Bbox& a, const Bbox& b) {
//                         float area_a = (a.x2 - a.x1) * (a.y2 - a.y1);
//                         float area_b = (b.x2 - b.x1) * (b.y2 - b.y1);
//                         return area_a < area_b;  // 按面积升序
//                     });
//                 // 只保留最小的框
//                 result.push_back(final_group[0]);
//             } 
//             else 
//             {
//                 // 否则保留所有未被包含的框
//                 for (auto& box : final_group) 
//                 {
//                     result.push_back(box);
//                 }
//             }
//         } 
//         else 
//         {
//             // 不足两个框，直接保留
//             for (auto& box : nms_result) 
//             {
//                 result.push_back(box);
//             }
//         }
//     }

//     return result;
// }

// 辅助函数：判断框a是否包含框b
bool RKNNDetector::contains(const Bbox& a, const Bbox& b)
{
    return (a.x1 <= b.x1 && a.y1 <= b.y1 &&
            a.x2 >= b.x2 && a.y2 >= b.y2);
}
